﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartMathLibrary.Statistics
{
    /// <summary>
    /// This class provides the creation of a linear trend function, which based on a specified timeseries.
    /// </summary>
    [Serializable]
    public class LinearTrendFunctionCreator
    {
        /// <summary>
        /// The timeseries on which the trend function should base.
        /// </summary>
        private TimeSeries series;

        /// <summary>
        /// Initializes a new instance of the <see cref="LinearTrendFunctionCreator"/> class.
        /// </summary>
        /// <param name="series">The timeseries on which the trend function should base.</param>
        public LinearTrendFunctionCreator(TimeSeries series)
        {
            if (series == (TimeSeries) null)
            {
                throw new ArgumentNullException("series");
            }

            this.series = series;
        }

        /// <summary>
        /// Gets or sets the timeseries on which the trend function should base.
        /// </summary>
        /// <value>The timeseries on which the trend function should base.</value>
        public TimeSeries Series
        {
            get { return this.series; }
            set { this.series = value; }
        }

        /// <summary>
        /// Creates the trend function.
        /// </summary>
        /// <returns>The created trend function.</returns>
        public LinearTrendFunction CreateTrendFunction()
        {
            double resultX = 0;
            double resultT = 0;
            GeneralVector indexVector = this.series.GenerateIndexVector();
            double avgT = Arrays.Avg(indexVector.VectorData);
            double avgX = Arrays.Avg(this.series.Data.VectorData);

            for (int i = 0; i < this.series.Data.Count; i++)
            {
                double tempuri = indexVector[i] - avgT;

                resultX += (this.series.Data[i] - avgX)*tempuri;
                resultT += Math.Pow(tempuri, 2);
            }

            double b = resultX/resultT;

            return new LinearTrendFunction(b, avgX - b*avgT);
        }
    }
}